#!/usr/bin/env bash
# Convenience script for loading firmware onto a jlink type device
# By default, initiates JLinkExe

AUTO_SCREEN_SESSION="/dev/kiibohd"
ERASE=0
NOSCREEN=1
GDB=0
NOCONNECT=0
SET_BOOT=0
PROG_NAME=$(basename $0)

# Parse all the command line arguments
while (( "$#" >= "1" )); do
	# Scan each argument
	key="$1"
	case $key in
	-e|--erase)
		ERASE=1
		shift
		;;
	-b|--boot)
		SET_BOOT=1
		shift
		;;
	-a|--autoscreen)
		NOSCREEN=0
		if [ ! -e "$2" ]; then
			AUTO_SCREEN_SESSION="$2"
		fi
		shift
		;;
	-g|--gdb)
		GDB=1
		shift
		;;
	-n|--noconnect)
		NOCONNECT=1
		shift
		;;
	-h|--help)
		echo "Usage: $PROG_NAME [options...]"
		echo ""
		echo "Loads the most recent built firmware (@TARGET_BIN@) to the device."
		echo "  (load.dfu)"
		echo ""
		echo "Arguments:"
		echo " -e, --erase                     Erase the whole chip before loading the firmware"
		echo " -b, --boot                      Enable boot from firmware bit"
		echo " -a, --autoscreen <SERIAL_PORT>  Use screen on the specified serial port after loading."
		echo "                                 e.g. /dev/ttyACM0"
		echo " -g, --gdb                       Automatically start a debug server"
		echo " -n, --noconnect                 Don't automatically connect with JLinkExe"
		echo " -h, --help                      This message."
		exit 1
		;;
	*)
		echo "INVALID ARG: '$1'"
		exit 2
		;;
	esac

	# Shift to the next argument
	shift
done

# Load via JLinkExe
# Used for development boards
if type JLinkExe &>/dev/null; then
	echo "connect" > flash.jlink
	if [[ $ERASE -eq 1 ]]; then
		echo "erase" >> flash.jlink
	fi
	echo "loadfile @TARGET_HEX@" >> flash.jlink
	if [[ $SET_BOOT -eq 1 ]]; then
		if [[ "@CHIP_SUPPORT@" == "sam" ]]; then
			# Set GPNVM bit 1 (boot flash0)
			echo "w4 0x400E0A04, 0x5A00010B" >> flash.jlink
			echo "sleep 20" >> flash.jlink
		fi
	fi
	echo "r" >> flash.jlink
	if [[ $GDB -ne 1 ]]; then
		echo "g" >> flash.jlink
	fi

	if [[ $NOCONNECT -ne 1 ]] && [[ $GDB -ne 1 ]]; then
		JLinkExe -device @CHIP@ -if @JLINK_INTERFACE@ -speed @JLINK_SPEED@ -CommanderScript flash.jlink -AutoConnect 1
	else
		echo "exit" >> flash.jlink
		JLinkExe -device @CHIP@ -if @JLINK_INTERFACE@ -speed @JLINK_SPEED@ -CommanderScript flash.jlink
	fi

	EXIT_STATUS=$?
else
	echo "JLinkExe is required to reprogram the device"
	exit 3
fi

# Load Screen Session if specified
if (( "$EXIT_STATUS" == "0" )); then
	if [[ $GDB -eq 1 ]]; then
		./debug -s	
	elif [[ "$AUTO_SCREEN_SESSION" != "" ]] && [[ $NOSCREEN -ne 1 ]]; then
		if type screen &>/dev/null; then
			echo "Waiting for serial device..."
			while [ ! -e $AUTO_SCREEN_SESSION ]; do
				sleep 0.1
			done
			screen $AUTO_SCREEN_SESSION
		else
			echo "screen is not installed"
			exit 3
		fi
	fi
fi

exit $EXIT_STATUS
